
function scrollClock(cup) {
    this.coef = 1
    // 定时器标记
    this.interSign = null;
    // 现在时间
    this.nowTimeSecond = 0;
    // 计时结束执行函数
    this.endFunction = null;
    // 按钮可用标志
    this.buttonSign = true;

    // 获得容器
    this.cup = cup;
    if(!this.cup) return false;

    // 在容器内创建结构
    this.__initStruct();


    // 获得组件
    this.ScrollClock = this.cup.querySelector(".ScrollClock");
    // 获得各个列表
    this.numberListList = this.ScrollClock.querySelectorAll(".numberList");
    // 获得控制组件
    this.clickPoint = this.ScrollClock.querySelector(".clickPoint");
    // 获得覆盖组件
    this.overHidden = this.ScrollClock.querySelector(".overHidden");

    this.__initNumberBox();
    this.__initScrollListen();
}

// 结构初始化
scrollClock.prototype.__initStruct = function() {
    let templet = `
        <div class="ScrollClock">
            <div class="clickPoint"></div>
            <div class="overHidden"></div>
            <span class="scrollClockBox">
                <div class="numberList"></div>
                <span class="signBox"> : </span>
                <div class="numberList"></div>
                <span class="signBox"> : </span>
                <div class="numberList"></div>
            </span>
        </div>
    `;
    this.cup.innerHTML = templet;
}

// 加入数字块
scrollClock.prototype.__initNumberBox = function() {
    this.numberListList.forEach((numberList, index) => {
        let temple = ``;
        let time = 60
        if(index === 0) time = 24;

        for(let i = 0; i < time; i++){
            temple += `
            <div class="numberBox">
                ${String(i).padStart(2, "0")}
            </div>
            `;
        }
        numberList.innerHTML = temple + temple + temple;
        numberList.scrollTop = numberList.scrollHeight / 3;
    });
}

// 滚动监测
scrollClock.prototype.__initScrollListen = function() {
    this.numberListList.forEach((numberList) => {
        numberList.addEventListener("scroll", () => {
            // 单项高度
            let itemHeight = numberList.firstElementChild?.getBoundingClientRect().height;
            if(!itemHeight) return false;
            // 组高度
            let itemGroupHeight = numberList.scrollHeight / 3;
            // 这里的 0.9 是为了自动翻滚时可以恰好跳转
            if(numberList.scrollTop < itemGroupHeight - itemHeight * 0.9)
                numberList.scrollTop = numberList.scrollHeight - itemGroupHeight - itemHeight;
            else if(numberList.scrollTop > numberList.scrollHeight - itemGroupHeight + itemHeight)
                numberList.scrollTop = itemGroupHeight + itemHeight;
        });
    });
}

// 返回容器
scrollClock.prototype.getCup = function() {
    return this.cup;
}

// 粘性滚动
scrollClock.prototype.addForceScroll = function() {
    this.numberListList.forEach((numberList) => {
        let timeout = null;
        numberList.addEventListener("scroll", () => {
            clearTimeout(timeout);
            timeout = setTimeout(() => {
                // @ts-ignore
                let itemHeight = numberList.firstElementChild.getBoundingClientRect().height;
                let nowIndex = Math.round(numberList.scrollTop / itemHeight);
                numberList.scrollTo({top: nowIndex * itemHeight, behavior: "smooth"});
            }, 100);
        });
    });
}

// 计时模式
scrollClock.prototype.addTimeMode = function() {
    this.clickPoint.addEventListener("click", () => {
        // 无计时器
        if(this.interSign === null) {
            this.__startClock();
        }
        // 有计时器
        else if(this.interSign !== null) {
            this.__endClock();
        }

    });
}

// 计时结束执行函数
scrollClock.prototype.__runEndFunction = function() {
    if(this.endFunction === null)
        return false;
    // 执行
    this.endFunction();
}

// 设置执行函数
scrollClock.prototype.addEndFunction = function(endFunction) {
    if(typeof endFunction !== "function")
        return false;
    this.endFunction = endFunction;
}

// 时间更新
scrollClock.prototype.__updataTime = function() {
    let power = 3600;
    let itemHeight = this.numberListList[0].firstElementChild.getBoundingClientRect().height;
    this.numberListList.forEach((numberList, index) => {
        // 懒更新
        if(this.nowTimeSecond % power !== 0) {
            power /= 60;
            return;
        }
        // 时间进制
        let baseTime = 60;
        if(index === 0) baseTime = 24;

        // 获取当前时间
        let nowTime = Math.floor((this.nowTimeSecond - 1) / power) % baseTime;
        power /= 60;

        // 获取滚动位置
        let nowScroll = itemHeight * (baseTime - 1 + ((nowTime + 1) % baseTime));

        numberList.scrollTo({top: nowScroll, behavior: "smooth"});
    });
}

// 校准用更新
scrollClock.prototype.__updataTimeForAdjust = function() {
    let power = 3600;
    let itemHeight = this.numberListList[0].firstElementChild.getBoundingClientRect().height;
    this.numberListList.forEach((numberList, index) => {
        // 时间进制
        let baseTime = 60;
        if(index === 0) baseTime = 24;

        // 获取当前时间
        let nowTime = Math.floor((this.nowTimeSecond) / power) % baseTime;
        power /= 60;

        // 获取滚动位置
        let nowScroll = itemHeight * (baseTime - 1 + ((nowTime + 1) % baseTime));

        numberList.scrollTo({top: nowScroll});
    });
}

// 开始计时
scrollClock.prototype.__startClock = function() {
    // 直接覆盖，防止操作
    this.overHidden.style.height = "100%";

    this.nowTimeSecond = 0;
    let itemHeight = this.numberListList[0].firstElementChild.getBoundingClientRect().height;

    // 获得时间
    this.numberListList.forEach((numberList) => {
        numberList.style.overflowY = "hidden";
        // 下标
        let index = Math.round(numberList.scrollTop / itemHeight);
        this.nowTimeSecond *= 60;

        this.nowTimeSecond += Number(numberList.querySelectorAll(".numberBox")[index].innerText);
        numberList.style.overflowY = "scroll";
    });

    // 导出总时间
    this.clickPoint.innerText = this.nowTimeSecond;

    // 校准
    this.__updataTimeForAdjust();
    this.interSign = setInterval(() => {
        // 计时结束
        if(this.nowTimeSecond <= 0) {
            this.__endClock();
            // 执行结束函数
            this.__runEndFunction();
            return true;
        }
        // 时间更新
        this.__updataTime();
        this.nowTimeSecond -= 1;

    }, 1000);
}

// 结束计时
scrollClock.prototype.__endClock = function() {
    if(this.interSign === null) return false;

    // 结束时按钮禁用
    this.buttonSign = false;

    clearInterval(this.interSign);
    this.interSign = null;

    this.numberListList.forEach((numberList) => {
        numberList.scrollTo({top: numberList.scrollHeight / 3, behavior: "smooth"});
    });

    this.clickPoint.innerText = "0";

    this.overHidden.style.height = "0";
    this.nowTimeSecond = 0;

    setTimeout(() => {
        this.buttonSign = true;
    }, 1000);
}

// 添加按钮
scrollClock.prototype.addButton = function(button) {
    button.addEventListener("click", () => {
        if(!this.buttonSign)
            return;
        this.clickPoint.click();
    });
}

// 设置大小
scrollClock.prototype.setSize = function(coef) {
    this.coef = coef || this.coef;
    this.ScrollClock.style.setProperty("--controlLen", String(window.innerWidth * this.coef));
    // 复位
    this.__updataTimeForAdjust();
}

function createScrollClock(selector) {
    return new scrollClock(selector || null);
}

export var ScrollClock = createScrollClock;